<template>
  <el-tree
    ref="dicTree"
    :data="trees"
    :default-expand-all="true"
    :highlight-current="true"
    :props="props"
    :expand-on-click-node="false"
    :show-checkbox="isMultiple"
    :current-node-key="chioseKey"
    :default-checked-keys="checkboxKey"
    :check-strictly="checkstrictly"
    node-key="Value"
    @node-click="chioseItem"
    @check-change="checkChange"
  >
    <span slot-scope="{ node, data }" class="slot-t-node">
      <template>
        <icon v-if="data.style" :icon="data.style.icon" :style="{ color: data.style.color, marginRight: '5px' }" />
        <span>{{ node.label }}</span>
      </template>
    </span>
  </el-tree>
</template>

<script>
import { getTrees } from '@/api/base/treeDicItem'
import { GetName } from '@/api/base/dict'

export default {
  components: {
  },
  props: {
    isMultiple: {
      type: Boolean,
      default: false
    },
    parentId: {
      type: String,
      default: null
    },
    checkstrictly: {
      type: Boolean,
      default: false
    },
    isChoiceEnd: {
      type: Boolean,
      default: true
    },
    isAutoChiose: {
      type: Boolean,
      default: false
    },
    dicId: {
      type: String,
      default: null
    },
    value: {
      default: null
    }
  },
  data() {
    return {
      trees: [],
      chioseKey: null,
      checkboxKey: [],
      deptDic: {},
      name: null,
      treeCache: {},
      dicName: null,
      props: {
        key: 'Value',
        label: 'Name',
        children: 'Children'
      }
    }
  },
  computed: {
    isDark() {
      return this.$store.getters.theme === 'dark'
    }
  },
  watch: {
    dicId: {
      handler(val) {
        if (val) {
          this.reset()
        }
      },
      immediate: true
    },
    parentId: {
      handler(val) {
        this.loadTree()
      },
      immediate: false
    },
    value: {
      handler(val) {
        if (this.isMultiple) {
          if (val == null) {
            this.checkboxKey = []
          } else {
            this.checkboxKey = Array.isArray(val) ? val : [val]
          }
        } else {
          this.chioseKey = val
        }
      },
      immediate: true
    }
  },
  methods: {
    async reset() {
      const name = await GetName(this.dicId)
      this.dicName = name
      this.loadTree()
    },
    initTree(res) {
      const data = {
        Value: 'root',
        Name: this.dicName,
        disabled: true,
        style: {
          icon: 'el-icon-s-flag',
          color: '#43AF2B'
        },
        Children: null
      }
      this.initChildren(data, res)
      this.trees = [data]
    },
    initChildren(data, list) {
      if (this.isNull(list)) {
        return
      }
      data.Children = list.map(c => {
        this.treeCache[c.DicValue] = {
          id: c.Id,
          text: c.DicText,
          value: c.DicValue,
          pId: data.Id
        }
        const item = {
          Name: c.DicText,
          Value: c.DicValue,
          disabled: false,
          style: {
            icon: 'el-icon-folder',
            color: this.isDark ? '#fff' : '#000'
          },
          Children: null
        }
        this.initChildren(item, c.Children)
        if (item.Children == null || item.Children.length === 0) {
          item.style.icon = 'file'
          item.style.color = '#409eff'
        } else {
          item.disabled = this.isChoiceEnd
        }
        return item
      })
    },
    isNull(array) {
      return array == null || array.length === 0
    },
    findDef(list) {
      if (this.isNull(list)) {
        return null
      }
      for (let i = 0; i < list.length; i++) {
        const item = list[i]
        if (!item.disabled) {
          return item.Value
        }
        const def = this.findDef(item.Children)
        if (def) {
          return def
        }
      }
      return null
    },
    async loadTree() {
      const res = await getTrees(this.dicId, this.parentId)
      this.initTree(res)
      const e = {
        isMultiple: this.isMultiple,
        tree: this.treeCache,
        value: []
      }
      if (this.chioseKey == null) {
        if (this.isAutoChiose && res.length > 0) {
          const val = this.findDef(res)
          if (val != null) {
            e.value.push(val)
            if (this.isMultiple) {
              this.checkboxKey = [val]
              this.$emit('input', this.checkboxKey)
            } else {
              this.chioseKey = val
              this.$emit('input', val)
            }
          }
        }
      } else if (this.isMultiple) {
        e.value = this.checkboxKey
      } else {
        e.value.push(this.chioseKey)
      }
      this.$emit('load', e)
    },
    autoChiose(data) {
      if (data.Children && data.Children.length !== 0) {
        let isSet = false
        data.Children.forEach((c) => {
          if (!this.checkboxKey.includes(c.Value)) {
            this.checkboxKey.push(c.Value)
            isSet = true
            this.autoChiose(c)
          }
        })
        return isSet
      }
      return false
    },
    checkChange(data, checked, indeterminate) {
      const index = this.checkboxKey.findIndex((c) => c === data.Value)
      if (checked) {
        if (index !== -1) {
          return
        }
        this.checkboxKey.push(data.Value)
        if (this.autoChiose(data)) {
          this.$refs.dicTree.setCheckedKeys(this.checkboxKey, false)
        }
      } else if (index === -1) {
        return
      } else {
        this.checkboxKey.splice(index, 1)
      }
      const e = {
        isMultiple: this.isMultiple,
        tree: this.treeCache,
        value: this.checkboxKey
      }
      this.$emit('input', this.checkboxKey)
      this.$emit('change', e)
    },
    chioseItem(item) {
      this.chioseKey = item.Value
      const e = {
        isMultiple: this.isMultiple,
        tree: this.treeCache,
        value: [this.chioseKey]
      }
      this.$emit('input', this.chioseKey)
      this.$emit('change', e)
    }
  }
}
</script>
